import 'dart:developer';
import 'dart:io';

import 'package:file_saver/src/models/file.model.dart';
import 'package:file_saver/src/platform_handler/platform_handler.dart';
import 'package:file_saver/src/utils/helpers.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

PlatformHandler getPlatformHandler() {
  return PlatformHandlerAll();
}

class PlatformHandlerAll extends PlatformHandler {
  final MethodChannel _channel = const MethodChannel('file_saver');
  final String _saveAs = 'saveAs';
  final String _saveFile = 'saveFile';

  final String _somethingWentWrong = 'Something went wrong, please report the issue https://www.github.com/incrediblezayed/file_saver/issues';
  late String directory = _somethingWentWrong;

  final String _issueLink = 'https://www.github.com/incrediblezayed/file_saver/issues';

  Future<String> saveFileForAndroid(FileModel fileModel) async {
    try {
      directory = await _channel.invokeMethod<String>(_saveFile, fileModel.toMap()) ?? '';
      return directory;
    } catch (e) {
      rethrow;
    }
  }

  Future<String> saveFileForOtherPlatforms(FileModel fileModel) async {
    String path = '';
    if (fileModel.path != null) {
      path = fileModel.path!;
    } else {
      path = await Helpers.getDirectory() ?? '';
    }
    if (path == '') {
      log('The path was found null or empty, please report the issue at $_issueLink');
      throw Exception('The path was found null or empty');
    } else {
      String filePath = '$path/${fileModel.name}${fileModel.ext}';
      debugPrint('Saving File path: $filePath');
      final File file = File(filePath);
      await file.writeAsBytes(fileModel.bytes);
      bool exist = await file.exists();
      if (exist) {
        directory = file.path;
      } else {
        log('File was not created');
      }
    }
    return directory;
  }

  @override
  Future<String?> saveFile(FileModel fileModel) async {
    // if (Platform.isAndroid) {
    //   return await saveFileForAndroid(fileModel);
    // } else {
    //   return await saveFileForOtherPlatforms(fileModel);
    // }

    return await saveFileForOtherPlatforms(fileModel);
  }

  ///Open File Manager
  @override
  Future<String?> saveAs(FileModel fileModel) async {
    String? path;
    if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
      path = await _channel.invokeMethod<String>(_saveAs, fileModel.toMap());
    } else if (Platform.isWindows) {
      final Int64List? bytes = await _channel.invokeMethod<Int64List?>('saveAs', fileModel.toMap());
      path = bytes == null ? null : String.fromCharCodes(bytes);
    } else {
      throw UnimplementedError('Unimplemented Error');
    }
    return path;
  }

  @override

  /// Opens the folder at given path.
  ///
  /// [path] is the path to the folder you want to open
  ///
  /// Returns true if the folder is opened successfully, false otherwise
  Future<bool> openFolder(String path) async {
    debugPrint('openFolder: $path');
    if (Platform.isAndroid) {
      return await _channel.invokeMethod('openFolder', {'path': path});
    }
    return false;
  }
}
